<template>
<div :class="[$style.container]">
  <el-dropdown trigger="click" placement="bottom-start" v-if="offset > 0">
    <el-link :underline="false" class="mx-2"><i class="el-icon-more"></i></el-link>
    <el-dropdown-menu slot="dropdown">
      <el-dropdown-item v-for="(row, i) in hiddenRows" :key="i" @click.native="onGoto(row)">
        <span v-for="j in i" :key="j" class="ml-2"></span>
        <span><i class="el-icon-folder"></i></span>
        <span>{{row.label}}</span>
      </el-dropdown-item>
    </el-dropdown-menu>
  </el-dropdown>
  <div :class="[$style.wrap]">
    <ul :class="[$style.list]" :style="listStyle" ref="list" v-show="!editting">
      <li :class="[$style.item]" v-for="(row, i) in rows" :key="i">
        <el-link :underline="false" :class="[$style.text]" @click="onGoto(row)" v-if="!row.last">{{row.label}}</el-link>
        <span class="text-secondary" :class="[$style.text]" v-else>{{row.label}}</span>
        <span v-if="!row.last"><i class="el-icon-arrow-right"></i></span>
      </li>
    </ul>
    <div :class="[$style.inputWrap]" @keyup.enter="onConfirm" v-show="editting">
      <el-input v-model="value" size="small" :class="[$style.input]" ref="input"></el-input>
      <div :class="[$style.inputAction]">
        <el-button type="primary" size="mini" :disabled="value === (data && data.path)" @click="onConfirm">跳转</el-button>
        <el-button size="mini" @click="onCancel">取消</el-button>
      </div>
    </div>
  </div>
  <div :class="[$style.actions]" v-show="!editting">
    <el-link :underline="false" @click="onCopy"><i class="el-icon-copy-document"></i></el-link>
    <el-link :underline="false" class="ml-2" @click="onEdit"><i class="el-icon-edit"></i></el-link>
    <el-link :underline="false" class="ml-2" @click="load()"><i class="el-icon-refresh"></i></el-link>
  </div>
</div>
</template>

<script lang="ts">

import { Vue, Component, Prop, Emit, Inject, Ref } from 'vue-property-decorator'
import { getDocByPath } from '@/api/doc'
import { copyToClipboard } from '@/utils/copy'
import { AppModule } from '@/store'

@Component
export default class DocPath extends Vue {
  @Prop() data!: any

  @AppModule.State currentSpace!: any

  @Ref() list!: HTMLElement

  @Inject() load!: () => void

  offset = 0

  idx = 0

  editting = false

  value = ''

  get rows () {
    const ret = (this.data?.path || '').split('/')
    return ret.map((v: string, i: number) => {
      return {
        path: ret.slice(0, i + 1).join('/'),
        label: i === 0 ? this.currentSpace.name : v,
        last: i === ret.length - 1,
        level: i
      }
    })
  }

  get hiddenRows () {
    return this.rows.slice(0, this.idx)
  }

  get listStyle () {
    return {
      marginLeft: -this.offset + 'px'
    }
  }

  onGoto (row: any) {
    if (row.level === 0) {
      this.$router.push({ path: this.$route.path })
      return
    }
    getDocByPath(row.path).then(data => {
      if (!data) {
        this.$message.error('文档不存在')
        return
      }
      this.$router.push({ path: this.$route.path, query: { id: data?.id } })
    })
  }

  onCopy () {
    copyToClipboard(this.data?.path)
    this.$message.success('已复制到粘贴板')
  }

  onEdit () {
    this.value = this.data?.path || ''
    this.editting = true
    this.$nextTick(() => {
      const $e = this.$refs.input as HTMLInputElement
      if ($e) $e.focus()
    })
  }

  onCancel () {
    this.value = ''
    this.editting = false
  }

  onConfirm () {
    if (!this.value) return
    getDocByPath(this.value).then(data => {
      if (!data) {
        this.$message.error('文档不存在')
        return
      }
      if (data?.type !== 'dir') {
        this.$message.error('请输入文件夹地址')
        return
      }
      this.$router.push({ path: this.$route.path, query: { id: data?.id } })
      this.editting = false
    })
  }

  refresh () {
    const childrenWidthsFn = () => {
      const children = this.list.querySelectorAll('li')
      const ret: number[] = []
      for (let i = 0; i < children.length; i++) {
        ret.push(children[i].offsetWidth)
      }
      return ret
    }

    const subWidthList = childrenWidthsFn()

    const offsetWidth = this.list.offsetWidth
    // const scrollWidth = this.list.scrollWidth
    const realWidth = subWidthList.reduce((t, n) => t + n, 0) // 实际宽度
    const viewWidth = offsetWidth - this.offset
    let offset = realWidth - viewWidth
    if (offset > 0) {
      let sum = 0
      subWidthList.some((w, i) => {
        if (offset > sum && i <= subWidthList.length - 1) {
          sum += w
          return false
        } else {
          offset = sum
          this.idx = i
          return true
        }
      })
    } else {
      this.idx = 0
    }
    this.offset = Math.max(0, offset)
  }

  updated () {
    this.refresh()
  }

  mounted () {
    const refreshHandler = () => {
      this.refresh()
    }
    window.addEventListener('resize', refreshHandler)
    this.$once('hook:beforeDestroy', function () {
      window.removeEventListener('resize', refreshHandler)
    })
  }
}
</script>

<style lang="scss" module>
@import "~@/styles/vars.scss";

.container {
  display: flex;
  width: 0;
  min-width: 100%;
}

.wrap {
  flex: 1 1 auto;
  overflow: hidden;
}

.list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
}

.item {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
}

.actions {
  margin-left: 12px;
  flex: 0 0 auto;
}

.text {
  display: inline-block;
  max-width: 320px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.inputWrap {
  display: flex;
  align-items: center;
}

.input {
  flex: 1 1 auto;
}

.inputAction {
  margin-left: 12px;
  flex: 0 0 auto;
}

</style>
